// Copyright 2025 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// Code generated by sidekick. DO NOT EDIT.

#![allow(rustdoc::redundant_explicit_links)]
#![allow(rustdoc::broken_intra_doc_links)]
#![no_implicit_prelude]
extern crate async_trait;
extern crate bytes;
extern crate gax;
extern crate gaxi;
extern crate gtype;
extern crate iam_v1;
extern crate lazy_static;
extern crate reqwest;
extern crate rpc;
extern crate serde;
extern crate serde_json;
extern crate serde_with;
extern crate std;
extern crate tracing;
extern crate wkt;

mod debug;
mod deserialize;
mod serialize;

/// Request for
/// [TroubleshootIamPolicy][google.cloud.policytroubleshooter.v1.IamChecker.TroubleshootIamPolicy].
///
/// [google.cloud.policytroubleshooter.v1.IamChecker.TroubleshootIamPolicy]: crate::client::IamChecker::troubleshoot_iam_policy
#[derive(Clone, Default, PartialEq)]
#[non_exhaustive]
pub struct TroubleshootIamPolicyRequest {
    /// The information to use for checking whether a principal has a permission
    /// for a resource.
    pub access_tuple: std::option::Option<crate::model::AccessTuple>,

    pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
}

impl TroubleshootIamPolicyRequest {
    pub fn new() -> Self {
        std::default::Default::default()
    }

    /// Sets the value of [access_tuple][crate::model::TroubleshootIamPolicyRequest::access_tuple].
    pub fn set_access_tuple<T>(mut self, v: T) -> Self
    where
        T: std::convert::Into<crate::model::AccessTuple>,
    {
        self.access_tuple = std::option::Option::Some(v.into());
        self
    }

    /// Sets or clears the value of [access_tuple][crate::model::TroubleshootIamPolicyRequest::access_tuple].
    pub fn set_or_clear_access_tuple<T>(mut self, v: std::option::Option<T>) -> Self
    where
        T: std::convert::Into<crate::model::AccessTuple>,
    {
        self.access_tuple = v.map(|x| x.into());
        self
    }
}

impl wkt::message::Message for TroubleshootIamPolicyRequest {
    fn typename() -> &'static str {
        "type.googleapis.com/google.cloud.policytroubleshooter.v1.TroubleshootIamPolicyRequest"
    }
}

/// Response for
/// [TroubleshootIamPolicy][google.cloud.policytroubleshooter.v1.IamChecker.TroubleshootIamPolicy].
///
/// [google.cloud.policytroubleshooter.v1.IamChecker.TroubleshootIamPolicy]: crate::client::IamChecker::troubleshoot_iam_policy
#[derive(Clone, Default, PartialEq)]
#[non_exhaustive]
pub struct TroubleshootIamPolicyResponse {
    /// Indicates whether the principal has the specified permission for the
    /// specified resource, based on evaluating all of the applicable IAM policies.
    pub access: crate::model::AccessState,

    /// List of IAM policies that were evaluated to check the principal's
    /// permissions, with annotations to indicate how each policy contributed to
    /// the final result.
    ///
    /// The list of policies can include the policy for the resource itself. It can
    /// also include policies that are inherited from higher levels of the resource
    /// hierarchy, including the organization, the folder, and the project.
    ///
    /// To learn more about the resource hierarchy, see
    /// <https://cloud.google.com/iam/help/resource-hierarchy>.
    pub explained_policies: std::vec::Vec<crate::model::ExplainedPolicy>,

    /// The general errors contained in the troubleshooting response.
    pub errors: std::vec::Vec<rpc::model::Status>,

    pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
}

impl TroubleshootIamPolicyResponse {
    pub fn new() -> Self {
        std::default::Default::default()
    }

    /// Sets the value of [access][crate::model::TroubleshootIamPolicyResponse::access].
    pub fn set_access<T: std::convert::Into<crate::model::AccessState>>(mut self, v: T) -> Self {
        self.access = v.into();
        self
    }

    /// Sets the value of [explained_policies][crate::model::TroubleshootIamPolicyResponse::explained_policies].
    pub fn set_explained_policies<T, V>(mut self, v: T) -> Self
    where
        T: std::iter::IntoIterator<Item = V>,
        V: std::convert::Into<crate::model::ExplainedPolicy>,
    {
        use std::iter::Iterator;
        self.explained_policies = v.into_iter().map(|i| i.into()).collect();
        self
    }

    /// Sets the value of [errors][crate::model::TroubleshootIamPolicyResponse::errors].
    pub fn set_errors<T, V>(mut self, v: T) -> Self
    where
        T: std::iter::IntoIterator<Item = V>,
        V: std::convert::Into<rpc::model::Status>,
    {
        use std::iter::Iterator;
        self.errors = v.into_iter().map(|i| i.into()).collect();
        self
    }
}

impl wkt::message::Message for TroubleshootIamPolicyResponse {
    fn typename() -> &'static str {
        "type.googleapis.com/google.cloud.policytroubleshooter.v1.TroubleshootIamPolicyResponse"
    }
}

/// Information about the principal, resource, and permission to check.
#[derive(Clone, Default, PartialEq)]
#[non_exhaustive]
pub struct AccessTuple {
    /// Required. The principal whose access you want to check, in the form of
    /// the email address that represents that principal. For example,
    /// `alice@example.com` or
    /// `my-service-account@my-project.iam.gserviceaccount.com`.
    ///
    /// The principal must be a Google Account or a service account. Other types of
    /// principals are not supported.
    pub principal: std::string::String,

    /// Required. The full resource name that identifies the resource. For example,
    /// `//compute.googleapis.com/projects/my-project/zones/us-central1-a/instances/my-instance`.
    ///
    /// For examples of full resource names for Google Cloud services, see
    /// <https://cloud.google.com/iam/help/troubleshooter/full-resource-names>.
    pub full_resource_name: std::string::String,

    /// Required. The IAM permission to check for the specified principal and
    /// resource.
    ///
    /// For a complete list of IAM permissions, see
    /// <https://cloud.google.com/iam/help/permissions/reference>.
    ///
    /// For a complete list of predefined IAM roles and the permissions in each
    /// role, see <https://cloud.google.com/iam/help/roles/reference>.
    pub permission: std::string::String,

    pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
}

impl AccessTuple {
    pub fn new() -> Self {
        std::default::Default::default()
    }

    /// Sets the value of [principal][crate::model::AccessTuple::principal].
    pub fn set_principal<T: std::convert::Into<std::string::String>>(mut self, v: T) -> Self {
        self.principal = v.into();
        self
    }

    /// Sets the value of [full_resource_name][crate::model::AccessTuple::full_resource_name].
    pub fn set_full_resource_name<T: std::convert::Into<std::string::String>>(
        mut self,
        v: T,
    ) -> Self {
        self.full_resource_name = v.into();
        self
    }

    /// Sets the value of [permission][crate::model::AccessTuple::permission].
    pub fn set_permission<T: std::convert::Into<std::string::String>>(mut self, v: T) -> Self {
        self.permission = v.into();
        self
    }
}

impl wkt::message::Message for AccessTuple {
    fn typename() -> &'static str {
        "type.googleapis.com/google.cloud.policytroubleshooter.v1.AccessTuple"
    }
}

/// Details about how a specific IAM [Policy][google.iam.v1.Policy] contributed
/// to the access check.
///
/// [google.iam.v1.Policy]: iam_v1::model::Policy
#[derive(Clone, Default, PartialEq)]
#[non_exhaustive]
pub struct ExplainedPolicy {
    /// Indicates whether _this policy_ provides the specified permission to the
    /// specified principal for the specified resource.
    ///
    /// This field does _not_ indicate whether the principal actually has the
    /// permission for the resource. There might be another policy that overrides
    /// this policy. To determine whether the principal actually has the
    /// permission, use the `access` field in the
    /// [TroubleshootIamPolicyResponse][IamChecker.TroubleshootIamPolicyResponse].
    pub access: crate::model::AccessState,

    /// The full resource name that identifies the resource. For example,
    /// `//compute.googleapis.com/projects/my-project/zones/us-central1-a/instances/my-instance`.
    ///
    /// If the sender of the request does not have access to the policy, this field
    /// is omitted.
    ///
    /// For examples of full resource names for Google Cloud services, see
    /// <https://cloud.google.com/iam/help/troubleshooter/full-resource-names>.
    pub full_resource_name: std::string::String,

    /// The IAM policy attached to the resource.
    ///
    /// If the sender of the request does not have access to the policy, this field
    /// is empty.
    pub policy: std::option::Option<iam_v1::model::Policy>,

    /// Details about how each binding in the policy affects the principal's
    /// ability, or inability, to use the permission for the resource.
    ///
    /// If the sender of the request does not have access to the policy, this field
    /// is omitted.
    pub binding_explanations: std::vec::Vec<crate::model::BindingExplanation>,

    /// The relevance of this policy to the overall determination in the
    /// [TroubleshootIamPolicyResponse][IamChecker.TroubleshootIamPolicyResponse].
    ///
    /// If the sender of the request does not have access to the policy, this field
    /// is omitted.
    pub relevance: crate::model::HeuristicRelevance,

    pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
}

impl ExplainedPolicy {
    pub fn new() -> Self {
        std::default::Default::default()
    }

    /// Sets the value of [access][crate::model::ExplainedPolicy::access].
    pub fn set_access<T: std::convert::Into<crate::model::AccessState>>(mut self, v: T) -> Self {
        self.access = v.into();
        self
    }

    /// Sets the value of [full_resource_name][crate::model::ExplainedPolicy::full_resource_name].
    pub fn set_full_resource_name<T: std::convert::Into<std::string::String>>(
        mut self,
        v: T,
    ) -> Self {
        self.full_resource_name = v.into();
        self
    }

    /// Sets the value of [policy][crate::model::ExplainedPolicy::policy].
    pub fn set_policy<T>(mut self, v: T) -> Self
    where
        T: std::convert::Into<iam_v1::model::Policy>,
    {
        self.policy = std::option::Option::Some(v.into());
        self
    }

    /// Sets or clears the value of [policy][crate::model::ExplainedPolicy::policy].
    pub fn set_or_clear_policy<T>(mut self, v: std::option::Option<T>) -> Self
    where
        T: std::convert::Into<iam_v1::model::Policy>,
    {
        self.policy = v.map(|x| x.into());
        self
    }

    /// Sets the value of [binding_explanations][crate::model::ExplainedPolicy::binding_explanations].
    pub fn set_binding_explanations<T, V>(mut self, v: T) -> Self
    where
        T: std::iter::IntoIterator<Item = V>,
        V: std::convert::Into<crate::model::BindingExplanation>,
    {
        use std::iter::Iterator;
        self.binding_explanations = v.into_iter().map(|i| i.into()).collect();
        self
    }

    /// Sets the value of [relevance][crate::model::ExplainedPolicy::relevance].
    pub fn set_relevance<T: std::convert::Into<crate::model::HeuristicRelevance>>(
        mut self,
        v: T,
    ) -> Self {
        self.relevance = v.into();
        self
    }
}

impl wkt::message::Message for ExplainedPolicy {
    fn typename() -> &'static str {
        "type.googleapis.com/google.cloud.policytroubleshooter.v1.ExplainedPolicy"
    }
}

/// Details about how a binding in a policy affects a principal's ability to use
/// a permission.
#[derive(Clone, Default, PartialEq)]
#[non_exhaustive]
pub struct BindingExplanation {
    /// Required. Indicates whether _this binding_ provides the specified
    /// permission to the specified principal for the specified resource.
    ///
    /// This field does _not_ indicate whether the principal actually has the
    /// permission for the resource. There might be another binding that overrides
    /// this binding. To determine whether the principal actually has the
    /// permission, use the `access` field in the
    /// [TroubleshootIamPolicyResponse][IamChecker.TroubleshootIamPolicyResponse].
    pub access: crate::model::AccessState,

    /// The role that this binding grants. For example,
    /// `roles/compute.serviceAgent`.
    ///
    /// For a complete list of predefined IAM roles, as well as the permissions in
    /// each role, see <https://cloud.google.com/iam/help/roles/reference>.
    pub role: std::string::String,

    /// Indicates whether the role granted by this binding contains the specified
    /// permission.
    pub role_permission: crate::model::binding_explanation::RolePermission,

    /// The relevance of the permission's existence, or nonexistence, in the role
    /// to the overall determination for the entire policy.
    pub role_permission_relevance: crate::model::HeuristicRelevance,

    /// Indicates whether each principal in the binding includes the principal
    /// specified in the request, either directly or indirectly. Each key
    /// identifies a principal in the binding, and each value indicates whether the
    /// principal in the binding includes the principal in the request.
    ///
    /// For example, suppose that a binding includes the following principals:
    ///
    /// * `user:alice@example.com`
    /// * `group:product-eng@example.com`
    ///
    /// You want to troubleshoot access for `user:bob@example.com`. This user is a
    /// principal of the group `group:product-eng@example.com`.
    ///
    /// For the first principal in the binding, the key is
    /// `user:alice@example.com`, and the `membership` field in the value is set to
    /// `MEMBERSHIP_NOT_INCLUDED`.
    ///
    /// For the second principal in the binding, the key is
    /// `group:product-eng@example.com`, and the `membership` field in the value is
    /// set to `MEMBERSHIP_INCLUDED`.
    pub memberships: std::collections::HashMap<
        std::string::String,
        crate::model::binding_explanation::AnnotatedMembership,
    >,

    /// The relevance of this binding to the overall determination for the entire
    /// policy.
    pub relevance: crate::model::HeuristicRelevance,

    /// A condition expression that prevents this binding from granting access
    /// unless the expression evaluates to `true`.
    ///
    /// To learn about IAM Conditions, see
    /// <https://cloud.google.com/iam/help/conditions/overview>.
    pub condition: std::option::Option<gtype::model::Expr>,

    pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
}

impl BindingExplanation {
    pub fn new() -> Self {
        std::default::Default::default()
    }

    /// Sets the value of [access][crate::model::BindingExplanation::access].
    pub fn set_access<T: std::convert::Into<crate::model::AccessState>>(mut self, v: T) -> Self {
        self.access = v.into();
        self
    }

    /// Sets the value of [role][crate::model::BindingExplanation::role].
    pub fn set_role<T: std::convert::Into<std::string::String>>(mut self, v: T) -> Self {
        self.role = v.into();
        self
    }

    /// Sets the value of [role_permission][crate::model::BindingExplanation::role_permission].
    pub fn set_role_permission<
        T: std::convert::Into<crate::model::binding_explanation::RolePermission>,
    >(
        mut self,
        v: T,
    ) -> Self {
        self.role_permission = v.into();
        self
    }

    /// Sets the value of [role_permission_relevance][crate::model::BindingExplanation::role_permission_relevance].
    pub fn set_role_permission_relevance<
        T: std::convert::Into<crate::model::HeuristicRelevance>,
    >(
        mut self,
        v: T,
    ) -> Self {
        self.role_permission_relevance = v.into();
        self
    }

    /// Sets the value of [memberships][crate::model::BindingExplanation::memberships].
    pub fn set_memberships<T, K, V>(mut self, v: T) -> Self
    where
        T: std::iter::IntoIterator<Item = (K, V)>,
        K: std::convert::Into<std::string::String>,
        V: std::convert::Into<crate::model::binding_explanation::AnnotatedMembership>,
    {
        use std::iter::Iterator;
        self.memberships = v.into_iter().map(|(k, v)| (k.into(), v.into())).collect();
        self
    }

    /// Sets the value of [relevance][crate::model::BindingExplanation::relevance].
    pub fn set_relevance<T: std::convert::Into<crate::model::HeuristicRelevance>>(
        mut self,
        v: T,
    ) -> Self {
        self.relevance = v.into();
        self
    }

    /// Sets the value of [condition][crate::model::BindingExplanation::condition].
    pub fn set_condition<T>(mut self, v: T) -> Self
    where
        T: std::convert::Into<gtype::model::Expr>,
    {
        self.condition = std::option::Option::Some(v.into());
        self
    }

    /// Sets or clears the value of [condition][crate::model::BindingExplanation::condition].
    pub fn set_or_clear_condition<T>(mut self, v: std::option::Option<T>) -> Self
    where
        T: std::convert::Into<gtype::model::Expr>,
    {
        self.condition = v.map(|x| x.into());
        self
    }
}

impl wkt::message::Message for BindingExplanation {
    fn typename() -> &'static str {
        "type.googleapis.com/google.cloud.policytroubleshooter.v1.BindingExplanation"
    }
}

/// Defines additional types related to [BindingExplanation].
pub mod binding_explanation {
    #[allow(unused_imports)]
    use super::*;

    /// Details about whether the binding includes the principal.
    #[derive(Clone, Default, PartialEq)]
    #[non_exhaustive]
    pub struct AnnotatedMembership {
        /// Indicates whether the binding includes the principal.
        pub membership: crate::model::binding_explanation::Membership,

        /// The relevance of the principal's status to the overall determination for
        /// the binding.
        pub relevance: crate::model::HeuristicRelevance,

        pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
    }

    impl AnnotatedMembership {
        pub fn new() -> Self {
            std::default::Default::default()
        }

        /// Sets the value of [membership][crate::model::binding_explanation::AnnotatedMembership::membership].
        pub fn set_membership<
            T: std::convert::Into<crate::model::binding_explanation::Membership>,
        >(
            mut self,
            v: T,
        ) -> Self {
            self.membership = v.into();
            self
        }

        /// Sets the value of [relevance][crate::model::binding_explanation::AnnotatedMembership::relevance].
        pub fn set_relevance<T: std::convert::Into<crate::model::HeuristicRelevance>>(
            mut self,
            v: T,
        ) -> Self {
            self.relevance = v.into();
            self
        }
    }

    impl wkt::message::Message for AnnotatedMembership {
        fn typename() -> &'static str {
            "type.googleapis.com/google.cloud.policytroubleshooter.v1.BindingExplanation.AnnotatedMembership"
        }
    }

    /// Whether a role includes a specific permission.
    ///
    /// # Working with unknown values
    ///
    /// This enum is defined as `#[non_exhaustive]` because Google Cloud may add
    /// additional enum variants at any time. Adding new variants is not considered
    /// a breaking change. Applications should write their code in anticipation of:
    ///
    /// - New values appearing in future releases of the client library, **and**
    /// - New values received dynamically, without application changes.
    ///
    /// Please consult the [Working with enums] section in the user guide for some
    /// guidelines.
    ///
    /// [Working with enums]: https://google-cloud-rust.github.io/working_with_enums.html
    #[derive(Clone, Debug, PartialEq)]
    #[non_exhaustive]
    pub enum RolePermission {
        /// Default value. This value is unused.
        Unspecified,
        /// The permission is included in the role.
        Included,
        /// The permission is not included in the role.
        NotIncluded,
        /// The sender of the request is not allowed to access the binding.
        UnknownInfoDenied,
        /// If set, the enum was initialized with an unknown value.
        ///
        /// Applications can examine the value using [RolePermission::value] or
        /// [RolePermission::name].
        UnknownValue(role_permission::UnknownValue),
    }

    #[doc(hidden)]
    pub mod role_permission {
        #[allow(unused_imports)]
        use super::*;
        #[derive(Clone, Debug, PartialEq)]
        pub struct UnknownValue(pub(crate) wkt::internal::UnknownEnumValue);
    }

    impl RolePermission {
        /// Gets the enum value.
        ///
        /// Returns `None` if the enum contains an unknown value deserialized from
        /// the string representation of enums.
        pub fn value(&self) -> std::option::Option<i32> {
            match self {
                Self::Unspecified => std::option::Option::Some(0),
                Self::Included => std::option::Option::Some(1),
                Self::NotIncluded => std::option::Option::Some(2),
                Self::UnknownInfoDenied => std::option::Option::Some(3),
                Self::UnknownValue(u) => u.0.value(),
            }
        }

        /// Gets the enum value as a string.
        ///
        /// Returns `None` if the enum contains an unknown value deserialized from
        /// the integer representation of enums.
        pub fn name(&self) -> std::option::Option<&str> {
            match self {
                Self::Unspecified => std::option::Option::Some("ROLE_PERMISSION_UNSPECIFIED"),
                Self::Included => std::option::Option::Some("ROLE_PERMISSION_INCLUDED"),
                Self::NotIncluded => std::option::Option::Some("ROLE_PERMISSION_NOT_INCLUDED"),
                Self::UnknownInfoDenied => {
                    std::option::Option::Some("ROLE_PERMISSION_UNKNOWN_INFO_DENIED")
                }
                Self::UnknownValue(u) => u.0.name(),
            }
        }
    }

    impl std::default::Default for RolePermission {
        fn default() -> Self {
            use std::convert::From;
            Self::from(0)
        }
    }

    impl std::fmt::Display for RolePermission {
        fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::result::Result<(), std::fmt::Error> {
            wkt::internal::display_enum(f, self.name(), self.value())
        }
    }

    impl std::convert::From<i32> for RolePermission {
        fn from(value: i32) -> Self {
            match value {
                0 => Self::Unspecified,
                1 => Self::Included,
                2 => Self::NotIncluded,
                3 => Self::UnknownInfoDenied,
                _ => Self::UnknownValue(role_permission::UnknownValue(
                    wkt::internal::UnknownEnumValue::Integer(value),
                )),
            }
        }
    }

    impl std::convert::From<&str> for RolePermission {
        fn from(value: &str) -> Self {
            use std::string::ToString;
            match value {
                "ROLE_PERMISSION_UNSPECIFIED" => Self::Unspecified,
                "ROLE_PERMISSION_INCLUDED" => Self::Included,
                "ROLE_PERMISSION_NOT_INCLUDED" => Self::NotIncluded,
                "ROLE_PERMISSION_UNKNOWN_INFO_DENIED" => Self::UnknownInfoDenied,
                _ => Self::UnknownValue(role_permission::UnknownValue(
                    wkt::internal::UnknownEnumValue::String(value.to_string()),
                )),
            }
        }
    }

    impl serde::ser::Serialize for RolePermission {
        fn serialize<S>(&self, serializer: S) -> std::result::Result<S::Ok, S::Error>
        where
            S: serde::Serializer,
        {
            match self {
                Self::Unspecified => serializer.serialize_i32(0),
                Self::Included => serializer.serialize_i32(1),
                Self::NotIncluded => serializer.serialize_i32(2),
                Self::UnknownInfoDenied => serializer.serialize_i32(3),
                Self::UnknownValue(u) => u.0.serialize(serializer),
            }
        }
    }

    impl<'de> serde::de::Deserialize<'de> for RolePermission {
        fn deserialize<D>(deserializer: D) -> std::result::Result<Self, D::Error>
        where
            D: serde::Deserializer<'de>,
        {
            deserializer.deserialize_any(wkt::internal::EnumVisitor::<RolePermission>::new(
                ".google.cloud.policytroubleshooter.v1.BindingExplanation.RolePermission",
            ))
        }
    }

    /// Whether the binding includes the principal.
    ///
    /// # Working with unknown values
    ///
    /// This enum is defined as `#[non_exhaustive]` because Google Cloud may add
    /// additional enum variants at any time. Adding new variants is not considered
    /// a breaking change. Applications should write their code in anticipation of:
    ///
    /// - New values appearing in future releases of the client library, **and**
    /// - New values received dynamically, without application changes.
    ///
    /// Please consult the [Working with enums] section in the user guide for some
    /// guidelines.
    ///
    /// [Working with enums]: https://google-cloud-rust.github.io/working_with_enums.html
    #[derive(Clone, Debug, PartialEq)]
    #[non_exhaustive]
    pub enum Membership {
        /// Default value. This value is unused.
        Unspecified,
        /// The binding includes the principal. The principal can be included
        /// directly or indirectly. For example:
        ///
        /// * A principal is included directly if that principal is listed in the
        ///   binding.
        /// * A principal is included indirectly if that principal is in a Google
        ///   group or Google Workspace domain that is listed in the binding.
        Included,
        /// The binding does not include the principal.
        NotIncluded,
        /// The sender of the request is not allowed to access the binding.
        UnknownInfoDenied,
        /// The principal is an unsupported type. Only Google Accounts and service
        /// accounts are supported.
        UnknownUnsupported,
        /// If set, the enum was initialized with an unknown value.
        ///
        /// Applications can examine the value using [Membership::value] or
        /// [Membership::name].
        UnknownValue(membership::UnknownValue),
    }

    #[doc(hidden)]
    pub mod membership {
        #[allow(unused_imports)]
        use super::*;
        #[derive(Clone, Debug, PartialEq)]
        pub struct UnknownValue(pub(crate) wkt::internal::UnknownEnumValue);
    }

    impl Membership {
        /// Gets the enum value.
        ///
        /// Returns `None` if the enum contains an unknown value deserialized from
        /// the string representation of enums.
        pub fn value(&self) -> std::option::Option<i32> {
            match self {
                Self::Unspecified => std::option::Option::Some(0),
                Self::Included => std::option::Option::Some(1),
                Self::NotIncluded => std::option::Option::Some(2),
                Self::UnknownInfoDenied => std::option::Option::Some(3),
                Self::UnknownUnsupported => std::option::Option::Some(4),
                Self::UnknownValue(u) => u.0.value(),
            }
        }

        /// Gets the enum value as a string.
        ///
        /// Returns `None` if the enum contains an unknown value deserialized from
        /// the integer representation of enums.
        pub fn name(&self) -> std::option::Option<&str> {
            match self {
                Self::Unspecified => std::option::Option::Some("MEMBERSHIP_UNSPECIFIED"),
                Self::Included => std::option::Option::Some("MEMBERSHIP_INCLUDED"),
                Self::NotIncluded => std::option::Option::Some("MEMBERSHIP_NOT_INCLUDED"),
                Self::UnknownInfoDenied => {
                    std::option::Option::Some("MEMBERSHIP_UNKNOWN_INFO_DENIED")
                }
                Self::UnknownUnsupported => {
                    std::option::Option::Some("MEMBERSHIP_UNKNOWN_UNSUPPORTED")
                }
                Self::UnknownValue(u) => u.0.name(),
            }
        }
    }

    impl std::default::Default for Membership {
        fn default() -> Self {
            use std::convert::From;
            Self::from(0)
        }
    }

    impl std::fmt::Display for Membership {
        fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::result::Result<(), std::fmt::Error> {
            wkt::internal::display_enum(f, self.name(), self.value())
        }
    }

    impl std::convert::From<i32> for Membership {
        fn from(value: i32) -> Self {
            match value {
                0 => Self::Unspecified,
                1 => Self::Included,
                2 => Self::NotIncluded,
                3 => Self::UnknownInfoDenied,
                4 => Self::UnknownUnsupported,
                _ => Self::UnknownValue(membership::UnknownValue(
                    wkt::internal::UnknownEnumValue::Integer(value),
                )),
            }
        }
    }

    impl std::convert::From<&str> for Membership {
        fn from(value: &str) -> Self {
            use std::string::ToString;
            match value {
                "MEMBERSHIP_UNSPECIFIED" => Self::Unspecified,
                "MEMBERSHIP_INCLUDED" => Self::Included,
                "MEMBERSHIP_NOT_INCLUDED" => Self::NotIncluded,
                "MEMBERSHIP_UNKNOWN_INFO_DENIED" => Self::UnknownInfoDenied,
                "MEMBERSHIP_UNKNOWN_UNSUPPORTED" => Self::UnknownUnsupported,
                _ => Self::UnknownValue(membership::UnknownValue(
                    wkt::internal::UnknownEnumValue::String(value.to_string()),
                )),
            }
        }
    }

    impl serde::ser::Serialize for Membership {
        fn serialize<S>(&self, serializer: S) -> std::result::Result<S::Ok, S::Error>
        where
            S: serde::Serializer,
        {
            match self {
                Self::Unspecified => serializer.serialize_i32(0),
                Self::Included => serializer.serialize_i32(1),
                Self::NotIncluded => serializer.serialize_i32(2),
                Self::UnknownInfoDenied => serializer.serialize_i32(3),
                Self::UnknownUnsupported => serializer.serialize_i32(4),
                Self::UnknownValue(u) => u.0.serialize(serializer),
            }
        }
    }

    impl<'de> serde::de::Deserialize<'de> for Membership {
        fn deserialize<D>(deserializer: D) -> std::result::Result<Self, D::Error>
        where
            D: serde::Deserializer<'de>,
        {
            deserializer.deserialize_any(wkt::internal::EnumVisitor::<Membership>::new(
                ".google.cloud.policytroubleshooter.v1.BindingExplanation.Membership",
            ))
        }
    }
}

/// Whether a principal has a permission for a resource.
///
/// # Working with unknown values
///
/// This enum is defined as `#[non_exhaustive]` because Google Cloud may add
/// additional enum variants at any time. Adding new variants is not considered
/// a breaking change. Applications should write their code in anticipation of:
///
/// - New values appearing in future releases of the client library, **and**
/// - New values received dynamically, without application changes.
///
/// Please consult the [Working with enums] section in the user guide for some
/// guidelines.
///
/// [Working with enums]: https://google-cloud-rust.github.io/working_with_enums.html
#[derive(Clone, Debug, PartialEq)]
#[non_exhaustive]
pub enum AccessState {
    /// Default value. This value is unused.
    Unspecified,
    /// The principal has the permission.
    Granted,
    /// The principal does not have the permission.
    NotGranted,
    /// The principal has the permission only if a condition expression evaluates
    /// to `true`.
    UnknownConditional,
    /// The sender of the request does not have access to all of the policies that
    /// Policy Troubleshooter needs to evaluate.
    UnknownInfoDenied,
    /// If set, the enum was initialized with an unknown value.
    ///
    /// Applications can examine the value using [AccessState::value] or
    /// [AccessState::name].
    UnknownValue(access_state::UnknownValue),
}

#[doc(hidden)]
pub mod access_state {
    #[allow(unused_imports)]
    use super::*;
    #[derive(Clone, Debug, PartialEq)]
    pub struct UnknownValue(pub(crate) wkt::internal::UnknownEnumValue);
}

impl AccessState {
    /// Gets the enum value.
    ///
    /// Returns `None` if the enum contains an unknown value deserialized from
    /// the string representation of enums.
    pub fn value(&self) -> std::option::Option<i32> {
        match self {
            Self::Unspecified => std::option::Option::Some(0),
            Self::Granted => std::option::Option::Some(1),
            Self::NotGranted => std::option::Option::Some(2),
            Self::UnknownConditional => std::option::Option::Some(3),
            Self::UnknownInfoDenied => std::option::Option::Some(4),
            Self::UnknownValue(u) => u.0.value(),
        }
    }

    /// Gets the enum value as a string.
    ///
    /// Returns `None` if the enum contains an unknown value deserialized from
    /// the integer representation of enums.
    pub fn name(&self) -> std::option::Option<&str> {
        match self {
            Self::Unspecified => std::option::Option::Some("ACCESS_STATE_UNSPECIFIED"),
            Self::Granted => std::option::Option::Some("GRANTED"),
            Self::NotGranted => std::option::Option::Some("NOT_GRANTED"),
            Self::UnknownConditional => std::option::Option::Some("UNKNOWN_CONDITIONAL"),
            Self::UnknownInfoDenied => std::option::Option::Some("UNKNOWN_INFO_DENIED"),
            Self::UnknownValue(u) => u.0.name(),
        }
    }
}

impl std::default::Default for AccessState {
    fn default() -> Self {
        use std::convert::From;
        Self::from(0)
    }
}

impl std::fmt::Display for AccessState {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::result::Result<(), std::fmt::Error> {
        wkt::internal::display_enum(f, self.name(), self.value())
    }
}

impl std::convert::From<i32> for AccessState {
    fn from(value: i32) -> Self {
        match value {
            0 => Self::Unspecified,
            1 => Self::Granted,
            2 => Self::NotGranted,
            3 => Self::UnknownConditional,
            4 => Self::UnknownInfoDenied,
            _ => Self::UnknownValue(access_state::UnknownValue(
                wkt::internal::UnknownEnumValue::Integer(value),
            )),
        }
    }
}

impl std::convert::From<&str> for AccessState {
    fn from(value: &str) -> Self {
        use std::string::ToString;
        match value {
            "ACCESS_STATE_UNSPECIFIED" => Self::Unspecified,
            "GRANTED" => Self::Granted,
            "NOT_GRANTED" => Self::NotGranted,
            "UNKNOWN_CONDITIONAL" => Self::UnknownConditional,
            "UNKNOWN_INFO_DENIED" => Self::UnknownInfoDenied,
            _ => Self::UnknownValue(access_state::UnknownValue(
                wkt::internal::UnknownEnumValue::String(value.to_string()),
            )),
        }
    }
}

impl serde::ser::Serialize for AccessState {
    fn serialize<S>(&self, serializer: S) -> std::result::Result<S::Ok, S::Error>
    where
        S: serde::Serializer,
    {
        match self {
            Self::Unspecified => serializer.serialize_i32(0),
            Self::Granted => serializer.serialize_i32(1),
            Self::NotGranted => serializer.serialize_i32(2),
            Self::UnknownConditional => serializer.serialize_i32(3),
            Self::UnknownInfoDenied => serializer.serialize_i32(4),
            Self::UnknownValue(u) => u.0.serialize(serializer),
        }
    }
}

impl<'de> serde::de::Deserialize<'de> for AccessState {
    fn deserialize<D>(deserializer: D) -> std::result::Result<Self, D::Error>
    where
        D: serde::Deserializer<'de>,
    {
        deserializer.deserialize_any(wkt::internal::EnumVisitor::<AccessState>::new(
            ".google.cloud.policytroubleshooter.v1.AccessState",
        ))
    }
}

/// The extent to which a single data point, such as the existence of a binding
/// or whether a binding includes a specific principal, contributes to an overall
/// determination.
///
/// # Working with unknown values
///
/// This enum is defined as `#[non_exhaustive]` because Google Cloud may add
/// additional enum variants at any time. Adding new variants is not considered
/// a breaking change. Applications should write their code in anticipation of:
///
/// - New values appearing in future releases of the client library, **and**
/// - New values received dynamically, without application changes.
///
/// Please consult the [Working with enums] section in the user guide for some
/// guidelines.
///
/// [Working with enums]: https://google-cloud-rust.github.io/working_with_enums.html
#[derive(Clone, Debug, PartialEq)]
#[non_exhaustive]
pub enum HeuristicRelevance {
    /// Default value. This value is unused.
    Unspecified,
    /// The data point has a limited effect on the result. Changing the data point
    /// is unlikely to affect the overall determination.
    Normal,
    /// The data point has a strong effect on the result. Changing the data point
    /// is likely to affect the overall determination.
    High,
    /// If set, the enum was initialized with an unknown value.
    ///
    /// Applications can examine the value using [HeuristicRelevance::value] or
    /// [HeuristicRelevance::name].
    UnknownValue(heuristic_relevance::UnknownValue),
}

#[doc(hidden)]
pub mod heuristic_relevance {
    #[allow(unused_imports)]
    use super::*;
    #[derive(Clone, Debug, PartialEq)]
    pub struct UnknownValue(pub(crate) wkt::internal::UnknownEnumValue);
}

impl HeuristicRelevance {
    /// Gets the enum value.
    ///
    /// Returns `None` if the enum contains an unknown value deserialized from
    /// the string representation of enums.
    pub fn value(&self) -> std::option::Option<i32> {
        match self {
            Self::Unspecified => std::option::Option::Some(0),
            Self::Normal => std::option::Option::Some(1),
            Self::High => std::option::Option::Some(2),
            Self::UnknownValue(u) => u.0.value(),
        }
    }

    /// Gets the enum value as a string.
    ///
    /// Returns `None` if the enum contains an unknown value deserialized from
    /// the integer representation of enums.
    pub fn name(&self) -> std::option::Option<&str> {
        match self {
            Self::Unspecified => std::option::Option::Some("HEURISTIC_RELEVANCE_UNSPECIFIED"),
            Self::Normal => std::option::Option::Some("NORMAL"),
            Self::High => std::option::Option::Some("HIGH"),
            Self::UnknownValue(u) => u.0.name(),
        }
    }
}

impl std::default::Default for HeuristicRelevance {
    fn default() -> Self {
        use std::convert::From;
        Self::from(0)
    }
}

impl std::fmt::Display for HeuristicRelevance {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::result::Result<(), std::fmt::Error> {
        wkt::internal::display_enum(f, self.name(), self.value())
    }
}

impl std::convert::From<i32> for HeuristicRelevance {
    fn from(value: i32) -> Self {
        match value {
            0 => Self::Unspecified,
            1 => Self::Normal,
            2 => Self::High,
            _ => Self::UnknownValue(heuristic_relevance::UnknownValue(
                wkt::internal::UnknownEnumValue::Integer(value),
            )),
        }
    }
}

impl std::convert::From<&str> for HeuristicRelevance {
    fn from(value: &str) -> Self {
        use std::string::ToString;
        match value {
            "HEURISTIC_RELEVANCE_UNSPECIFIED" => Self::Unspecified,
            "NORMAL" => Self::Normal,
            "HIGH" => Self::High,
            _ => Self::UnknownValue(heuristic_relevance::UnknownValue(
                wkt::internal::UnknownEnumValue::String(value.to_string()),
            )),
        }
    }
}

impl serde::ser::Serialize for HeuristicRelevance {
    fn serialize<S>(&self, serializer: S) -> std::result::Result<S::Ok, S::Error>
    where
        S: serde::Serializer,
    {
        match self {
            Self::Unspecified => serializer.serialize_i32(0),
            Self::Normal => serializer.serialize_i32(1),
            Self::High => serializer.serialize_i32(2),
            Self::UnknownValue(u) => u.0.serialize(serializer),
        }
    }
}

impl<'de> serde::de::Deserialize<'de> for HeuristicRelevance {
    fn deserialize<D>(deserializer: D) -> std::result::Result<Self, D::Error>
    where
        D: serde::Deserializer<'de>,
    {
        deserializer.deserialize_any(wkt::internal::EnumVisitor::<HeuristicRelevance>::new(
            ".google.cloud.policytroubleshooter.v1.HeuristicRelevance",
        ))
    }
}
